<!--
 * @Author       : wfl
 * @LastEditors: zdl
 * @description  :
 * @updateInfo   :
 * @Date         : 2023-05-10 15:39:33
 * @LastEditTime: 2023-12-21 10:40:27
-->
<script setup lang="ts" name="WaitApply">
import { ElMessage } from 'element-plus'
import { IKApprovalProcess } from 'iking-web-ui'
import EmptySvg from '@g/components/svg/empty_svg.vue'
import { _ } from 'iking-utils'
import { EFlowFormType, EPermissionType } from '../enum'
import type { detail, sendData } from './interface'
import { formApi } from '@/MainApp/apis/approve-center'
import { systemConfig } from '@/system.config'

const { operateCol } = useConfig()
const { baseUrl, loadUrl } = useHttpUrl()
const formJson = ref(null)
const route = useRoute()
const { userList, depList, handSetChild } = usePickerData()
const { msgSuccess, msgError, msgBoxWarnAsync } = useMessage()
const vFormRef: Ref<any | null> = ref(null)
const processRef: Ref<any | null> = ref(null)
const detailData: Ref<detail | null> = shallowRef(null)

const qloading = ref(false)
const showDraftBox = ref(false)
let formData: any = {}
const router = useRouter()

let MicroFormCom: any = null
try {
  const moudle: any = import.meta.glob('../../../../MicroApp/**/*.vue')

  if (systemConfig.arrpove?.componentPath)
    MicroFormCom = defineAsyncComponent(moudle[`../../../../MicroApp/${systemConfig.arrpove?.componentPath}`])
}
catch (error) {

}

// 查询流程预览信息
const queryPreview = async (params = '') => {
  qloading.value = true
  const formId = route.query?.id as string
  const { success, data, msg } = await formApi.getFormPreview({
    previewType: 'BY_FORM_CONFIG',
    formId,
    formData: params
  })
  if (success) {
    formJson.value = JSON.parse(data.viewProperty)
    if (!params) {
      if (detailData.value?.type !== EFlowFormType.已有表单) {
        nextTick(() => {
          vFormRef.value?.setFormJson(formJson.value)
        })
      }
    }
    previewData.value = data

    previewData.value?.processInstance?.instanceNodes.forEach((pre: any) => {
      pre.executorUsers = pre.executorUsers?.map((i: any) => {
        return {
          ...i,
          userAvatar: (i.userAvatar && setFileUrl(i.userAvatar)) || '',
          canDele: i.approvalCategory === 'INITIATOR_SPECIFIED'
        }
      })
    })
  }
  else {
    ElMessage.error(msg)
  }
  qloading.value = false
}
const handFormChange = (data: string) => {
  if (typeof data !== 'string')
    throw new TypeError('form-change参数必须是json格式')

  else
    queryPreview(data)
}

// 获取表单详情
const queryFormDetail = async () => {
  try {
    const id = route.query?.id as string
    qloading.value = true
    const { success, data } = await formApi.getFormDetail(id)
    if (success) {
      detailData.value = data
      await queryPreview()

      try {
        const { process } = JSON.parse(data.process?.property || '{}')
        if (process) {
          const { permissions } = process
          if (detailData.value?.type !== EFlowFormType.已有表单) {
            nextTick(() => {
              permissions && permissions.forEach((item: any) => {
                if (item.permissionType === EPermissionType.只读)
                  vFormRef.value.disableWidgets([item.widgetName])

                else if (item.permissionType === EPermissionType.隐藏)
                  vFormRef.value.hideWidgets([item.widgetName])
              })
            })
          }
        }
      }
      catch (error) {

      }
    }
  }
  catch (error) {
    queryPreview()
    qloading.value = false
  }
}
queryFormDetail()

const previewData: Ref<sendData | null> = ref(null)
const { setFileUrl } = useHttpUrl()

const handleClose = () => {
  showDraftBox.value = false
}
const handBack = () => {
  router.push({
    path: '/approve-center/approve-list'
  })
}
const loading = ref(false)
const isCustomForm = computed(() => {
  return detailData.value?.type === EFlowFormType.已有表单
})
const refCustomForm: Ref<{ submitForm: Function; handleGetFormData?: Function; handleResetForm?: Function; } | null> = ref(null)
// 页面最大宽度
const maxwidth = computed(() => isCustomForm.value ? 'auto' : '800px')
const handSubmit = async () => {
  draftPropData.value = null
  const pass = processRef?.value?.requiredVerification()
  if (pass) {
    try {
      loading.value = true
      try {
        previewData.value?.processInstance?.instanceNodes?.forEach((item: any) => {
          item?.executorUsers.forEach((i: any) => {
            i.userId ??= i.elementId
          })
        })
      }
      catch (error) {
      }
      let customFormData = {}
      // 已有表单
      if (isCustomForm.value) {
        const data = await refCustomForm?.value?.submitForm?.(previewData.value)
        if (!data)
          return
        else
          customFormData = data
      }
      const formData = isCustomForm.value ? customFormData : vFormRef?.value?.formDataModel
      const formDataSummary: any = isCustomForm.value
        ? {}
        : dealData(
          formData,
          vFormRef?.value?.widgetList
        )
      const param = {
        ...previewData.value,
        businessDataId: isCustomForm.value ? formData?.id : previewData.value?.businessDataId,
        formData: JSON.stringify(formData),
        formDataSummary: JSON.stringify(formDataSummary)
      }
      const { success, msg } = await formApi.submitApprove(param)
      if (success) {
        msgSuccess(msg)
        router.back()
      }
      else {
        msgError(msg)
      }
      loading.value = false
    }
    catch (error) {
      console.info('error', error)
      loading.value = false
    }
  }
}
const handSubmitApprove = async () => {
  // 已有表单不走表单验证
  if (detailData.value?.type === EFlowFormType.已有表单) {
    handSubmit()
    return
  }
  vFormRef?.value?.validateForm(async (valid: any) => {
    if (valid)
      handSubmit()
  })
}
const dealData = (formData: any, widgetsList: any) => {
  const data: any = []
  const widgetsLength = widgetsList.length
  for (let i = 0; i < widgetsLength && data.length < 3; i++) {
    const item = widgetsList[i]
    const { id, options } = item
    if (id in formData) {
      if (options?.optionItems && options?.optionItems?.length > 0) {
        const map = options?.optionItems.reduce((result: any, item: any) => {
          result[item.value] = item.label
          return result
        }, {})
        const labels
          = formData[id]?.map?.((value: any) => map[value]) || map[formData[id]]
        data.push({
          label: item?.options?.label,
          value: labels.join?.(',') || labels
        })
      }
      else {
        data.push({
          label: item?.options?.label,
          value: formData[item.id]
        })
      }
    }
  }
  return data
}
const changedRender = async (key: any, value: any) => {
  if (isDraft.value)
    return
  if (!formData[key] || formData[key] !== value) {
    const data = vFormRef.value?.formDataModel
    formData = _.cloneDeep(data)
    try {
      await queryPreview(JSON.stringify(data) || '')
    }
    catch (error) {

    }
  }
  // getSelectedLabel
}

// 保存草稿
const loadingDraft = ref(false)
const draftData = ref([])
const draftPropData = ref(null)
const isDraft = ref(false)
const handToSaveDraft = async (isLocal = true, cusFormData?: any) => {
  const pass = processRef?.value?.requiredVerification()
  if (!pass)
    return
  loadingDraft.value = true
  const previewDataCopy = _.cloneDeep(previewData.value)
  try {
    previewDataCopy?.processInstance?.instanceNodes?.forEach((item: any) => {
      item?.executorUsers?.forEach((i: any) => {
        i.userId ??= i.elementId
      })
    })
    const widgetList = isLocal ? _.cloneDeep(vFormRef?.value?.widgetList) : []
    const formData = isLocal ? _.cloneDeep(vFormRef?.value?.formDataModel) : _.cloneDeep(cusFormData || {})
    const formDataSummary: any = detailData.value?.type === EFlowFormType.已有表单
      ? {}
      : dealData(
        formData,
        widgetList
      )
    const param = {
      ...previewDataCopy,
      formData: JSON.stringify(formData),
      formDataSummary: JSON.stringify(formDataSummary)
    }
    const { msg, success } = await formApi.addDraft(param)
    loadingDraft.value = false
    if (success) {
      msgSuccess(msg)
      queryFormDetail()
      queryDraft()
      refCustomForm.value?.handleResetForm?.()
    }
    else { msgError(msg) }
  }
  catch (error) {
    console.error('error: ', error)
  }
}
const handSaveDraft = async () => {
  // 已有表单
  if (detailData?.value?.type === EFlowFormType.已有表单) {
    // TODO 添加审批草稿获取业务表单数据文档
    refCustomForm.value?.handleGetFormData?.().then((res: any) => {
      if (typeof res === 'object')
        handToSaveDraft(false, res)
    })
  }
  else {
    vFormRef?.value?.validateForm(async (valid: any) => {
      if (valid)
        handToSaveDraft(true)
    })
  }
  draftPropData.value = null
}
const draftForm = ref({
  page: 1,
  rows: 5,
  formId: route.query.id
})
const draftTotal = ref(0)
const queryDraftLoading = ref(false)
// 查询草稿
const queryDraft = async () => {
  queryDraftLoading.value = true
  const { msg, success, data, total } = await formApi.queryDraft(draftForm.value)
  queryDraftLoading.value = false
  if (success) {
    draftData.value = data
    draftTotal.value = total
  }
  else {
    msgError(msg)
  }
}
queryDraft()
const showDraftDetail = () => {
  showDraftBox.value = true
  draftPropData.value = null
}
const isEditing = ref(false)
// 编辑草稿
const handEditDraft = async (row: any) => {
  const { success, data, msg } = await formApi.getFormPreview({
    previewType: 'BY_DRAFT',
    formInstanceId: row.id,
    formData: ''
  })
  if (success) {
    isEditing.value = true
    showDraftBox.value = false
    isDraft.value = true
    // 回显数据时不触发查询流程
    setTimeout(() => {
      isDraft.value = false
    })
    try {
      if (detailData.value?.type === EFlowFormType.已有表单)
        draftPropData.value = JSON.parse(data?.formData)
      else
        vFormRef.value?.setFormData(JSON.parse(data?.formData))

      previewData.value = data
      previewData.value?.processInstance?.instanceNodes.forEach((pre: any) => {
        // eslint-disable-next-line no-prototype-builtins
        if (pre && !pre.hasOwnProperty('initiatorSpecify'))
          pre.initiatorSpecify = true

        pre.executorUsers = pre.executorUsers?.map((i: any) => {
          return {
            ...i,
            userName: i?.elementName || i?.userName,
            userAvatar: (i.userAvatar && setFileUrl(i.userAvatar)) || '',
            canDele: pre.approvalCategory === 'INITIATOR_SPECIFIED'
          }
        })
      })
    }
    catch (error) {
      console.info('error: ', error)
    }
  }
  else {
    msgError(msg)
  }
}
// 删除草稿
const handDleteDraft = async (row: any) => {
  msgBoxWarnAsync('删除确认', '确认删除此草稿吗?', async () => {
    const { msg, success } = await formApi.deleteDraft(row.id)
    if (success) {
      msgSuccess(msg)
      queryDraft()
    }
    !success && msgError(msg)
  })
}
const handCurrentChange = (val: number) => {
  draftForm.value.page = val
  queryDraft()
}
</script>

<template>
  <IkPageMain fixed class="ikflow-wait-apply overflow-overlay">
    <IkPageHeader
      :title="detailData?.name"
      :icon="detailData?.icon"
      :background-color="detailData?.iconBackground"
      @back="handBack"
    >
      <template #right>
        <el-button @click="showDraftDetail">
          <template #icon>
            <i class="ikflow ikflow-jilu"></i>
          </template>
          草稿箱({{ draftTotal }})
        </el-button>
      </template>
    </IkPageHeader>
    <div v-loading="qloading" class="form-content">
      <el-card shadow="never" class="no-border border-left">
        <template #header>
          <span class="card-title">{{ detailData?.name }}</span>
        </template>
        <MicroFormCom
          v-if="systemConfig.arrpove?.componentPath && detailData?.type === EFlowFormType.已有表单"
          ref="refCustomForm"
          :data="detailData"
          :draft-data="_.cloneDeep(draftPropData)"
          :is-edit="true"
          @form-change="handFormChange"
        />
        <VFormRender v-else ref="vFormRef" @fieldChange="changedRender" />
      </el-card>
      <el-card shadow="never" class="no-border border-left">
        <template #header>
          <span class="card-title">流程</span>
        </template>
        <IKApprovalProcess
          ref="processRef"
          :data-list="previewData?.processInstance?.instanceNodes"
          :dep-list="depList"
          :user-list="userList"
          :picker-url="`${baseUrl}/server/component/pick/mix`"
          :load-url="loadUrl"
          @handChild="handSetChild"
        />
      </el-card>
    </div>
    <IkFooter>
      <el-button type="primary" @click="handSubmitApprove">提交</el-button>
      <el-button
        type="primary"
        plain
        :loading="loadingDraft"
        @click="handSaveDraft"
      >
        {{ !isEditing ? '保存草稿' : '更新草稿' }}
      </el-button>
    </IkFooter>
    <el-dialog
      v-model="showDraftBox"
      :width="700"
      :close="handleClose"
      align-center
      draggable
    >
      <template #title>
        <span>{{ `草稿箱 (${draftTotal})` }}</span>
        <span class="ik-info-text">（草稿箱适用于保存填写中还未提交的表单）</span>
      </template>
      <template v-if="draftData.length">
        <el-alert
          title="3个月内未更新的草稿将被自动删除"
          type="warning"
          show-icon
          :closable="false"
        />
        <el-table
          v-loading="queryDraftLoading"
          :data="draftData"
          stripe
          height="410"
          style="width: 100%;"
        >
          <el-table-column prop="title" label="标题" width="180" />
          <el-table-column prop="initiatorTime" label="创建时间" width="180" />
          <el-table-column prop="updateTime" label="更新时间" />
          <el-table-column label="操作" :width="operateCol.two">
            <template #default="{ row }">
              <IkSvgIcon
                name="icon-bianji"
                type="info"
                show-bg
                :start-margin="false"
                @click="handEditDraft(row)"
              />
              <IkSvgIcon name="icon-shanchu" show-bg @click="handDleteDraft(row)" />
            </template>
          </el-table-column>
        </el-table>
        <el-pagination
          background
          layout="prev, pager, next"
          :page-size="5"
          :total="draftTotal"
          class="flex flex-row justify-end relative top-[12px]"
          @current-change="handCurrentChange"
        />
      </template>
      <template v-else>
        <div class="drafg-empty">
          <EmptySvg style="width: 200px;" />
          <p>暂无草稿</p>
        </div>
      </template>
    </el-dialog>
  </IkPageMain>
</template>

<style lang="scss">
.ikflow-wait-apply {
  flex: 1;
  display: flex;
  flex-direction: column;

  .form-content {
    flex: 1;
    margin: 20px;
    display: -webkit-box;
    flex-direction: column;
    box-sizing: border-box;
    align-items: center;
    justify-content: flex-start;
    overflow: auto;

    .el-card {
      // max-width: 900px;
      width: 100%;
      max-width: v-bind('maxwidth');
      border-radius: 0;

      &:first-child {
        margin-bottom: 16px;
      }

      .card-title {
        font-size: 18px;
        font-weight: 600;
      }

      .approval-btn {
        padding: 16px;

        button {
          width: 100px;
        }
      }
    }
  }

  .drafg-empty {
    display: flex;
    align-items: center;
    flex-direction: column;
    height: 500px;
    justify-content: center;

    p {
      font-size: 16px;
      font-weight: 600;
    }
  }
}
</style>
